//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#include "NjExample01.h"
#include "NjTestUnit.h"

//----------------------------------------------------------------------------
class NjTestUnit::Static
{
public:
	static void WriteMessage(NjCharA const * szFormat, ...);

	NJ_DISABLE_INSTANCE(Static);
};
//----------------------------------------------------------------------------
void NjTestUnit::Flush()
{
	if (ms_szLastTestUnit==NJ_NULL)
		return;

	ms_szLastTestUnit=NJ_NULL;

	if (ms_uTotTests==0)
		return;

	NjTestUnit::Static::WriteMessage("Passed %d/%d\n\n", NjUint32(ms_uSuccessTests), NjUint32(ms_uTotTests));
	ms_uSuccessTests=0;
	ms_uTotTests=0;
}
//----------------------------------------------------------------------------
NjTestUnit::TestUnitsGroup::TestUnitsGroup(NjCharA const * szMessage)
{
	if (ms_szLastTestUnit!=NJ_NULL)
	{
		NjCharA const * szLeft(szMessage);
		NjCharA const * szRight(ms_szLastTestUnit);

		for(;;)
		{
			NjCharA const chLeft(*szLeft);
			NjCharA const chRight(*szRight);

			if (chLeft!=chRight)
				break;

			if (chLeft==0)
				return;

			++szLeft;
			++szRight;
		}
	}

	Flush();
	ms_szLastTestUnit=szMessage;
	NjTestUnit::Static::WriteMessage("%s tests\n", szMessage);
}
//----------------------------------------------------------------------------
NjTestUnit::TestUnitsGroup::~TestUnitsGroup()
{
}
//----------------------------------------------------------------------------
NjTestUnit::TestUnitsGroup::TestUnit::TestUnit(TestUnitsGroup * pGroup, NjCharA const * szMessage)
:
	m_bSuccess(NJ_TRUE)
{
	++ms_uTotTests;
	NjTestUnit::Static::WriteMessage(" - %s ... ", szMessage);
	NJ_UNUSED_VAR(pGroup);
}
//----------------------------------------------------------------------------
NjTestUnit::TestUnitsGroup::TestUnit::~TestUnit()
{
	if (m_bSuccess)
	{
		++ms_uSuccessTests;
		NjTestUnit::Static::WriteMessage("success\n");
	}
}
//----------------------------------------------------------------------------
NjBool NjTestUnit::TestUnitsGroup::TestUnit::Test(NjBool bCondition, NjCharA const * szCondition, NjCharA const * szMessage, NjCharA const * szFile, NjUint uLine, NjCharA const * szFunction)
{
	if (bCondition)
		return NJ_TRUE;
		
	if (szFile==NJ_NULL)
	 szFile="";

	if (szMessage==NJ_NULL)
	 szMessage="NJ_TEST failure";

	if (szFunction==NJ_NULL)
	 szFunction="";

	m_bSuccess=NJ_FALSE;
	NjTestUnit::ms_bUnitTestSuccess=NJ_FALSE;
	NjTestUnit::Static::WriteMessage("fail\n\n%s (%d): %s - %s\n\n", szFile, uLine, szFunction, szMessage);

	NJ_UNUSED_VAR(szCondition);
	NJ_UNUSED_VAR(szMessage);
	NJ_UNUSED_VAR(szFile);
	NJ_UNUSED_VAR(uLine);
	NJ_UNUSED_VAR(szFunction);
	return NJ_FALSE;
}
//----------------------------------------------------------------------------
void NjTestUnit::Static::WriteMessage(NjCharA const * szFormat, ...)
{
	NjCharA szMessage[1024];
	
	va_list kArgs;
	va_start(kArgs, szFormat);

#if NJ_PLATFORM_OS_WIN
	vsnprintf_s(szMessage, sizeof(szMessage)-1, sizeof(szMessage)-1, szFormat, kArgs);
#elif NJ_PLATFORM_OS_LINUX
	vsnprintf(szMessage, sizeof(szMessage)-1, szFormat, kArgs);
#else
#	error "Unsupported build configuration"
#endif

	va_end(kArgs);

	printf("%s", szMessage);
	fflush(stdout);
	NjDebugSystem::WriteToDebugConsole(szMessage);
}
//----------------------------------------------------------------------------
NjCharA const * NjTestUnit::ms_szLastTestUnit(NJ_NULL);
NjBool NjTestUnit::ms_bUnitTestSuccess(NJ_TRUE);
NjUint NjTestUnit::ms_uSuccessTests(0);
NjUint NjTestUnit::ms_uTotTests(0);
//----------------------------------------------------------------------------
